package com.alibaba.citrus.ots.sales.plan.repository;

import com.alibaba.acm.shaded.com.alibaba.metrics.StringUtils;
import com.alibaba.citrus.ots.sales.plan.dto.api.request.DepartRedLineQueryRequest;
import com.alibaba.citrus.ots.sales.plan.dto.api.request.PageQueryContractRequest;
import com.alibaba.citrus.ots.sales.plan.model.enums.ContractDataSourceEnum;
import com.alibaba.citrus.ots.sales.plan.model.enums.ContractStatDimensionEnum;
import com.alibaba.citrus.ots.sales.plan.sdo.ContractSDO;
import com.alibaba.citrus.ots.sales.plan.sdo.DepartmentContractRedLineSDO;
import com.alibaba.cz.base.tool.page.PageResult;
import com.alibaba.cz.base.tool.result.Result;
import com.epoch.app.bcots.model.dto.DepartmentContractRedLineLoadListRequest;
import com.epoch.app.bcots.sales_plan.contract.dto.BatchQueryByCustomerAddressAndScItemRequest;
import com.epoch.app.bcots.sales_plan.contract.dto.BatchQueryByCustomerAddressAndScItemResponse;
import com.epoch.app.bcots.sales_plan.contract.model.Contract;
import com.epoch.app.bcots.sales_plan.contract.service.ContractService;
import com.epoch.app.bcots.sales_plan.departmentcontractredline.dto.BatchCreateRedRatiosRequest;
import com.epoch.app.bcots.sales_plan.departmentcontractredline.dto.CreateDepartmentContractRedLineResponse;
import com.epoch.app.bcots.sales_plan.departmentcontractredline.model.DepartmentContractRedLine;
import com.epoch.app.bcots.sales_plan.departmentcontractredline.service.DepartmentContractRedLineService;
import com.google.common.collect.Lists;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;
import java.util.stream.IntStream;

/**
 * @author wangyibing
 */
@Component
public class DepartmentContractRedLineRepositoryImpl implements DepartmentContractRedLineRepository {

    @Resource
    private DepartmentContractRedLineService departmentContractRedLineService;

    @Resource
    private ContractRepository contractRepository;

    @Resource
    private ContractService contractService;


    @Override
    public Integer batchDepartmentContractRedLine(List<DepartmentContractRedLineSDO> departmentContractRedLineSDOS) {
        List<String> contractYears = departmentContractRedLineSDOS.stream().map(DepartmentContractRedLineSDO::getContractYear).distinct().collect(Collectors.toList());
        if (contractYears.size() > 0) {
            throw new RuntimeException("OTS-02-001-00-16-003");
        }
        String contractYear = contractYears.stream().findFirst().get();
        // 批量查询部门+货品的合同量汇总数据
        List<String> orgSalesDepartmentCodes = departmentContractRedLineSDOS.stream().map(DepartmentContractRedLineSDO::getOrgSalesDepartmentCode).distinct().filter(StringUtils::isNotBlank).collect(Collectors.toList());
        List<String> scItemIds = departmentContractRedLineSDOS.stream().map(DepartmentContractRedLineSDO::getScItemId).distinct().filter(StringUtils::isNotBlank).collect(Collectors.toList());
        BatchQueryByCustomerAddressAndScItemRequest addressAndScItemRequest = BatchQueryByCustomerAddressAndScItemRequest.builder().build();
        addressAndScItemRequest.setContractYear(contractYear);
        addressAndScItemRequest.setType(ContractStatDimensionEnum.DEPARTMENT_SC_ITEM.getCode());
        addressAndScItemRequest.setDataSource(ContractDataSourceEnum.CUSTOMER.getCode());
        addressAndScItemRequest.setScItemIds(scItemIds);
        addressAndScItemRequest.setOrgSalesDepartmentCodes(orgSalesDepartmentCodes);
        BatchQueryByCustomerAddressAndScItemResponse response = contractService.batchQueryByCustomerAddressAndScItem(addressAndScItemRequest);
        if (CollectionUtils.isEmpty(response.getResult()) || response.getResult().size() != departmentContractRedLineSDOS.size()) {
            throw new RuntimeException("OTS-02-001-00-16-004");
        }
        List<DepartmentContractRedLineSDO> sdoList = departmentContractRedLineSDOS.stream().map(item -> {
            List<Contract> contracts = response.getResult().stream().filter(it ->
                            it.getContractYear().equals(item.getContractYear())
                                    && it.getType().equals(item.getType())
                                    && it.getOrgSalesDepartmentCode().equals(item.getOrgSalesDepartmentCode())
                                    && it.getScItemId().equals(item.getScItemId()))
                    .collect(Collectors.toList());
            if (CollectionUtils.isNotEmpty(contracts) && contracts.size() == 1) {
                Contract contract = contracts.stream().findFirst().get();
                ContractSDO contractSDO = new ContractSDO();
                BeanUtils.copyProperties(contract, contractSDO);
                setRedCountToDepartSDO(contractSDO, item);
            }
            return item;
        }).collect(Collectors.toList());
        //调用批量新增方法
        batchCreateRedLines(sdoList);
        return sdoList.size();
    }

    @Override
    public String createContractRedLine(DepartmentContractRedLineSDO departmentContractRedLineSDO) {
        //1、根据计划年份、合同类型、业务单元、销售组织、销售渠道、销售部门、货品查出唯一的合同汇总明细
        PageQueryContractRequest pageQueryContractRequest = buildDepartmentContractQueryRequest(departmentContractRedLineSDO);
        PageResult<List<ContractSDO>> listPageResult = contractRepository.pageQuery(pageQueryContractRequest, false);
        if (CollectionUtils.isEmpty(listPageResult.getContent())) {
            throw new RuntimeException("OTS-02-001-00-16-002");
        }
        //2、根据入参的红线比例计算出红线量、入库
        List<DepartmentContractRedLineSDO> redLineSDOS = listPageResult.getContent().stream().map(depart -> {
            setRedCountToDepartSDO(depart, departmentContractRedLineSDO);
            return departmentContractRedLineSDO;
        }).collect(Collectors.toList());

        DepartmentContractRedLineSDO redLineSDO = redLineSDOS.stream().findFirst().get();
        DepartRedLineQueryRequest departRedLineQueryRequest = new DepartRedLineQueryRequest();
        departRedLineQueryRequest.setContractYear(redLineSDO.getContractYear());
        departRedLineQueryRequest.setOrgSalesDepartmentCode(redLineSDO.getOrgSalesDepartmentCode());
        departRedLineQueryRequest.setScItemId(redLineSDO.getScItemId());
        DepartmentContractRedLineSDO contractRedLineSDO = this.querySingleByDepartAndItem(departRedLineQueryRequest);
        if (Objects.isNull(contractRedLineSDO) || contractRedLineSDO.getScItemId() == null) {
            DepartmentContractRedLine departmentContractRedLine = new DepartmentContractRedLine();
            BeanUtils.copyProperties(redLineSDO, departmentContractRedLine);
            CreateDepartmentContractRedLineResponse response = departmentContractRedLineService.createDepartmentContractRedLine(departmentContractRedLine);
            return response.getLastInsertId();
        } else {
            DepartmentContractRedLine departmentContractRedLine = new DepartmentContractRedLine();
            BeanUtils.copyProperties(redLineSDO, departmentContractRedLine);
            departmentContractRedLine.setId(contractRedLineSDO.getId());
            departmentContractRedLineService.updateDepartmentContractRedLine(departmentContractRedLine);
            return String.valueOf(contractRedLineSDO.getId());
        }
    }

    @Override
    public Result<Boolean> batchUpdateRedCount() {
        //获取总页数
        DepartmentContractRedLineLoadListRequest loadListRequest =
                DepartmentContractRedLineLoadListRequest.newDepartmentContractRedLineLoadListRequestBuilder().build();
        loadListRequest.setLimit(200);
        com.alibaba.lattice2.epoch.sdk.model.Result<List<DepartmentContractRedLine>> listResult = departmentContractRedLineService.loadDepartmentContractRedLineList(loadListRequest);
        int total = listResult.getTotal();
        int pageCount = getPageCount(total, loadListRequest.getLimit());
        if (pageCount == 0) {
            return Result.success(true);
        }
        //分页更新
        IntStream.rangeClosed(1, pageCount).forEach(page -> {
            loadListRequest.setPage(page);
            // 查询当前页的部门红线比例
            com.alibaba.lattice2.epoch.sdk.model.Result<List<DepartmentContractRedLine>> redLineList =
                    departmentContractRedLineService.loadDepartmentContractRedLineList(loadListRequest);
            List<DepartmentContractRedLine> redLines = redLineList.getResult();
            List<DepartmentContractRedLineSDO> redLineSDOS = redLines.stream().map(it -> {

                DepartmentContractRedLineSDO departmentContractRedLineSDO = new DepartmentContractRedLineSDO();
                BeanUtils.copyProperties(it, departmentContractRedLineSDO);
                //1、根据计划年份、合同类型、业务单元、销售组织、销售渠道、销售部门、货品查出唯一的合同汇总明细
                PageQueryContractRequest pageQueryContractRequest = buildDepartmentContractQueryRequest(departmentContractRedLineSDO);
                PageResult<List<ContractSDO>> listPageResult = contractRepository.pageQuery(pageQueryContractRequest,false);
                if (CollectionUtils.isEmpty(listPageResult.getContent())) {
                    throw new RuntimeException("OTS-02-001-00-16-002");
                }
                ContractSDO contractSDO = listPageResult.getContent().stream().findFirst().get();
                //根据查询到的合同量计算对应的红线量
                setRedCountToDepartSDO(contractSDO, departmentContractRedLineSDO);
                return departmentContractRedLineSDO;
            }).collect(Collectors.toList());
            //批量新增
            batchCreateRedLines(redLineSDOS);
        });
        return Result.success(true);
    }

    @Override
    public DepartmentContractRedLineSDO querySingleByDepartAndItem(DepartRedLineQueryRequest departRedLineQueryRequest) {
        DepartmentContractRedLineLoadListRequest loadListRequest = DepartmentContractRedLineLoadListRequest.newDepartmentContractRedLineLoadListRequestBuilder().build();
        loadListRequest.setContractYear(departRedLineQueryRequest.getContractYear());
        loadListRequest.setOrgSalesDepartmentCode(departRedLineQueryRequest.getOrgSalesDepartmentCode());
        loadListRequest.setScItemId(departRedLineQueryRequest.getScItemId());
        com.alibaba.lattice2.epoch.sdk.model.Result<List<DepartmentContractRedLine>> listResult =
                departmentContractRedLineService.loadDepartmentContractRedLineList(loadListRequest);
        if (Objects.isNull(listResult) || CollectionUtils.isEmpty(listResult.getResult())) {
            return null;
        }
        DepartmentContractRedLine departmentContractRedLine = listResult.getResult().stream().findFirst().get();
        DepartmentContractRedLineSDO departmentContractRedLineSDO = new DepartmentContractRedLineSDO();
        BeanUtils.copyProperties(departmentContractRedLine, departmentContractRedLineSDO);
        return departmentContractRedLineSDO;
    }

    private void batchCreateRedLines(List<DepartmentContractRedLineSDO> redLineSDOS) {
        List<DepartmentContractRedLine> departmentContractRedLines = redLineSDOS.stream().map(it -> {
            DepartmentContractRedLine departmentContractRedLine = new DepartmentContractRedLine();
            BeanUtils.copyProperties(it, departmentContractRedLine);
            return departmentContractRedLine;
        }).collect(Collectors.toList());
        BatchCreateRedRatiosRequest ratiosRequest = BatchCreateRedRatiosRequest.builder().departmentRedRatios(departmentContractRedLines).build();
        departmentContractRedLineService.batchCreateRedRatios(ratiosRequest);
    }

    private int getPageCount(int total, int limit) {
        if (total % limit == 0) {
            return total / limit;
        } else {
            return (total / limit) + 1;
        }
    }

    private void setRedCountToDepartSDO(ContractSDO contractSDO, DepartmentContractRedLineSDO departmentContractRedLineSDO) {
        if (Objects.nonNull(contractSDO.getJanQuantity()) && Objects.nonNull(departmentContractRedLineSDO.getJanRedRatio())) {
            contractSDO.setJanRedCount(new BigDecimal(contractSDO.getJanQuantity() * departmentContractRedLineSDO.getJanRedRatio()).multiply(new BigDecimal(0.01).setScale(2, BigDecimal.ROUND_HALF_UP)).intValue());
        }
        if (Objects.nonNull(contractSDO.getFebQuantity()) && Objects.nonNull(departmentContractRedLineSDO.getFebRedRatio())) {
            departmentContractRedLineSDO.setFebRedCount(new BigDecimal(contractSDO.getFebQuantity() * departmentContractRedLineSDO.getFebRedRatio()).multiply(new BigDecimal(0.01).setScale(2, BigDecimal.ROUND_HALF_UP)).intValue());

        }
        if (Objects.nonNull(contractSDO.getMarQuantity()) && Objects.nonNull(departmentContractRedLineSDO.getMarRedRatio())) {
            departmentContractRedLineSDO.setMarRedCount(new BigDecimal(contractSDO.getMarQuantity() * departmentContractRedLineSDO.getMarRedRatio()).multiply(new BigDecimal(0.01).setScale(2, BigDecimal.ROUND_HALF_UP)).intValue());
        }
        if (Objects.nonNull(contractSDO.getAprQuantity()) && Objects.nonNull(departmentContractRedLineSDO.getAprRedRatio())) {
            departmentContractRedLineSDO.setAprRedCount(new BigDecimal(contractSDO.getAprQuantity() * departmentContractRedLineSDO.getAprRedRatio()).multiply(new BigDecimal(0.01).setScale(2, BigDecimal.ROUND_HALF_UP)).intValue());
        }
        if (Objects.nonNull(contractSDO.getMayQuantity()) && Objects.nonNull(departmentContractRedLineSDO.getMayRedRatio())) {
            departmentContractRedLineSDO.setMayRedCount(new BigDecimal(contractSDO.getMayQuantity() * departmentContractRedLineSDO.getMayRedRatio()).multiply(new BigDecimal(0.01).setScale(2, BigDecimal.ROUND_HALF_UP)).intValue());
        }
        if (Objects.nonNull(contractSDO.getJuneQuantity()) && Objects.nonNull(departmentContractRedLineSDO.getJuneRedRatio())) {
            departmentContractRedLineSDO.setJuneRedCount(new BigDecimal(contractSDO.getJuneQuantity() * departmentContractRedLineSDO.getJuneRedRatio()).multiply(new BigDecimal(0.01).setScale(2, BigDecimal.ROUND_HALF_UP)).intValue());
        }
        if (Objects.nonNull(contractSDO.getJulyQuantity()) && Objects.nonNull(departmentContractRedLineSDO.getJulyRedRatio())) {
            departmentContractRedLineSDO.setJulyRedCount(new BigDecimal(contractSDO.getJulyQuantity() * departmentContractRedLineSDO.getJulyRedRatio()).multiply(new BigDecimal(0.01).setScale(2, BigDecimal.ROUND_HALF_UP)).intValue());
        }
        if (Objects.nonNull(contractSDO.getAugQuantity()) && Objects.nonNull(departmentContractRedLineSDO.getAugRedRatio())) {
            departmentContractRedLineSDO.setAugRedCount(new BigDecimal(contractSDO.getAugQuantity() * departmentContractRedLineSDO.getAugRedRatio()).multiply(new BigDecimal(0.01).setScale(2, BigDecimal.ROUND_HALF_UP)).intValue());
        }
        if (Objects.nonNull(contractSDO.getSeptQuantity()) && Objects.nonNull(departmentContractRedLineSDO.getSeptRedRatio())) {
            departmentContractRedLineSDO.setSeptRedCount(new BigDecimal(contractSDO.getSeptQuantity() * departmentContractRedLineSDO.getSeptRedRatio()).multiply(new BigDecimal(0.01).setScale(2, BigDecimal.ROUND_HALF_UP)).intValue());
        }
        if (Objects.nonNull(contractSDO.getOctQuantity()) && Objects.nonNull(departmentContractRedLineSDO.getOctRedRatio())) {
            departmentContractRedLineSDO.setOctRedCount(new BigDecimal(contractSDO.getOctQuantity() * departmentContractRedLineSDO.getOctRedRatio()).multiply(new BigDecimal(0.01).setScale(2, BigDecimal.ROUND_HALF_UP)).intValue());
        }
        if (Objects.nonNull(contractSDO.getNovQuantity()) && Objects.nonNull(departmentContractRedLineSDO.getNovRedRatio())) {
            departmentContractRedLineSDO.setNovRedCount(new BigDecimal(contractSDO.getNovQuantity() * departmentContractRedLineSDO.getNovRedRatio()).multiply(new BigDecimal(0.01).setScale(2, BigDecimal.ROUND_HALF_UP)).intValue());
        }
        if (Objects.nonNull(contractSDO.getDecQuantity()) && Objects.nonNull(departmentContractRedLineSDO.getDecRedRatio())) {
            departmentContractRedLineSDO.setDecRedCount(new BigDecimal(contractSDO.getDecQuantity() * departmentContractRedLineSDO.getDecRedRatio()).multiply(new BigDecimal(0.01).setScale(2, BigDecimal.ROUND_HALF_UP)).intValue());

        }

    }

    private PageQueryContractRequest buildDepartmentContractQueryRequest(DepartmentContractRedLineSDO departmentContractRedLineSDO) {

        PageQueryContractRequest pageQueryContractRequest = new PageQueryContractRequest();
        pageQueryContractRequest.setContractYear(departmentContractRedLineSDO.getContractYear());
        pageQueryContractRequest.setType(ContractStatDimensionEnum.DEPARTMENT_SC_ITEM.getCode());
        pageQueryContractRequest.setOrgBusinessUnitCode(departmentContractRedLineSDO.getOrgBusinessUnitCode());
        pageQueryContractRequest.setOrgSalesOrganizationCode(departmentContractRedLineSDO.getOrgSalesOrganizationCode());
        pageQueryContractRequest.setOrgSalesChannelCode(departmentContractRedLineSDO.getOrgSalesChannelCode());
        pageQueryContractRequest.setOrgSalesDepartmentCode(departmentContractRedLineSDO.getOrgSalesDepartmentCode());
        pageQueryContractRequest.setScItemIds(Lists.newArrayList(departmentContractRedLineSDO.getScItemId()));
        return pageQueryContractRequest;
    }
}
